import sys
import os
import ctypes
import ctypes.wintypes
from PySide6.QtWidgets import (QApplication, QMainWindow, QTreeView, QSplitter, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QStatusBar, QMenu, QInputDialog, QMessageBox, QFileSystemModel, QTextEdit)
from PySide6.QtGui import QIcon, QFont, QKeySequence, QAction, QShortcut
from PySide6.QtCore import Qt
import configparser
config = configparser.ConfigParser()
a = config.read("./config.conf", encoding="utf-8")
IS_WINDOWS = sys.platform.startswith('win')
if IS_WINDOWS:
    try:
        shell32 = ctypes.CDLL('shell32.dll', use_last_error=True)
        shell32.ShellExecuteW.argtypes = [
            ctypes.wintypes.HWND,
            ctypes.c_wchar_p,
            ctypes.c_wchar_p,
            ctypes.c_wchar_p,
            ctypes.c_wchar_p,
            ctypes.wintypes.INT
        ]
        shell32.ShellExecuteW.restype = ctypes.wintypes.HINSTANCE
        SW_SHOWNORMAL = 1
    except OSError:
        IS_WINDOWS = False

class ModernFileManager(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(config.get("start", "title"))
        self.resize(1000, 600)
        
        
        # 创建快捷键: Shift+B返回上级目录
        self.back_shortcut = QShortcut(QKeySequence("Shift+B"), self)
        self.back_shortcut.activated.connect(self.go_to_parent)
        
        # 创建主部件和布局
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QVBoxLayout(main_widget)
        
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        
        # 创建文件树视图
        self.tree_view = QTreeView()
        self.tree_view.setAnimated(True)
        self.tree_view.setIndentation(20)
        
        # 设置文件系统模型
        self.model = QFileSystemModel()
        self.model.setRootPath(os.path.expanduser("~"))
        self.current_root = self.model.index(os.path.expanduser("~"))
        self.tree_view.setModel(self.model)
        self.tree_view.setRootIndex(self.current_root)
        
        # 隐藏不需要的列
        for col in [1, 2, 3]:
            self.tree_view.setColumnHidden(col, True)
        
        # 右侧文件预览面板
        self.preview_panel = QWidget()
        preview_layout = QVBoxLayout(self.preview_panel)
        
        self.preview_title = QLabel("文件预览 (Shift+B返回上级)")
        self.preview_title.setStyleSheet("font-size: 16px; font-weight: bold; margin: 10px 0;")
        preview_layout.addWidget(self.preview_title)
        
        self.preview_text = QTextEdit()
        self.preview_text.setReadOnly(True)
        self.preview_text.setStyleSheet("background-color: #f9f9f9; border: 1px solid #ddd;")
        preview_layout.addWidget(self.preview_text)
        
        splitter.addWidget(self.tree_view)
        splitter.addWidget(self.preview_panel)
        splitter.setSizes([300, 700])
        
        main_layout.addWidget(splitter)
        
        # 状态栏 - 显示快捷键提示
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage(config.get("start", "whenopen"))
        
        # 连接信号槽
        self.tree_view.clicked.connect(self.update_status)
        self.tree_view.doubleClicked.connect(self.on_double_click)
        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view.customContextMenuRequested.connect(self.show_context_menu)
        
        # 应用样式
        self.apply_styles()
        
    def apply_styles(self):
        self.setStyleSheet("""
            QTreeView::item:hover {
                background-color: #e3f2fd;
                border-left: 3px solid #2196F3;
            }
            QTreeView::item:selected {
                background-color: #bbdefb;
                color: #0d47a1;
            }
            QStatusBar {
                background-color: #f5f5f5;
                color: #666;
                border-top: 1px solid #ddd;
            }
            QTextEdit {
                font-family: Consolas, 'Courier New', monospace;
            }
            QLabel {
                color: #333;
            }
        """)
        
    def update_status(self, index):
        path = self.model.filePath(index)
        
        # 预览文本文件
        if not self.model.isDir(index):
            file_ext = os.path.splitext(path)[1].lower()
            bin_extensions = ['.sys', '.dll', '.exe', '.bin']
            
            if file_ext not in bin_extensions:
                self.preview_title.setText(f"文件预览: {self.model.fileName(index)} (Shift+B返回上级)")
                try:
                    if os.path.getsize(path) < 1 * 1024 * 1024:  # 1MB限制
                        with open(path, 'r', encoding='utf-8') as f:
                            content = f.read()
                        self.preview_text.setText(content)
                    else:
                        self.preview_text.setText("文件过大，不支持预览（超过1MB）")
                except UnicodeDecodeError:
                    try:
                        with open(path, 'r', encoding='gbk') as f:
                            content = f.read()
                        self.preview_text.setText(content)
                    except Exception as e:
                        self.preview_text.setText(f"无法预览")
                except Exception as e:
                    self.preview_text.setText(f"无法预览")
            else:
                self.preview_title.setText(f"文件预览: {self.model.fileName(index)} (Shift+B返回上级)")
                self.preview_text.setText("不支持预览二进制文件或未知格式文件")
        else:
            self.preview_title.setText(f"文件夹预览: {self.model.fileName(index)} (Shift+B返回上级)")
            self.preview_text.setText(f"文件夹路径: {path}\n双击文件夹进入")
            
        # 更新状态栏
        if self.model.isDir(index):
            self.status_bar.showMessage(f"快捷键: Shift+B 返回上级目录 | 文件夹: {self.model.fileName(index)}")
        else:
            size = self.model.size(index)
            self.status_bar.showMessage(f"快捷键: Shift+B 返回上级目录 | 文件: {self.model.fileName(index)} ({size} bytes)")
            
    def on_double_click(self, index):
        if self.model.isDir(index):
            self.current_root = index
            self.tree_view.setRootIndex(index)
        else:
            self.open_file(index)
            
    def go_to_parent(self):
        parent_index = self.current_root.parent()
        if parent_index.isValid():
            self.current_root = parent_index
            self.tree_view.setRootIndex(parent_index)
            self.status_bar.showMessage(f"快捷键: Shift+B 返回上级目录 | 已返回上级目录")
            
    def show_context_menu(self, position):
        index = self.tree_view.indexAt(position)
        if not index.isValid():
            return
            
        menu = QMenu()
        open_action = QAction("打开", self)
        rename_action = QAction("重命名", self)
        delete_action = QAction("删除", self)
        
        if IS_WINDOWS and 'shell32' in globals():
            show_in_explorer_action = QAction("在资源管理器中显示", self)
            show_in_explorer_action.triggered.connect(lambda: self.show_in_explorer(index))
            menu.addAction(show_in_explorer_action)
            
        open_action.triggered.connect(lambda: self.open_file(index))
        rename_action.triggered.connect(lambda: self.rename_item(index))
        delete_action.triggered.connect(lambda: self.delete_item(index))
        
        menu.addAction(open_action)
        menu.addAction(rename_action)
        menu.addAction(delete_action)
        
        menu.exec_(self.tree_view.viewport().mapToGlobal(position))
        
    def open_file(self, index):
        if not self.model.isDir(index):
            path = self.model.filePath(index)
            if IS_WINDOWS and 'shell32' in globals():
                result = shell32.ShellExecuteW(None, "open", path, None, None, SW_SHOWNORMAL)
                if result <= 32:
                    QMessageBox.critical(self, "错误", f"无法打开文件: {path}")
            else:
                import subprocess
                try:
                    if sys.platform == 'darwin':
                        subprocess.run(['open', path])
                    elif sys.platform.startswith('linux'):
                        subprocess.run(['xdg-open', path])
                    else:
                        QMessageBox.warning(self, "不支持", "文件打开功能在当前系统中不可用")
                except Exception as e:
                    QMessageBox.critical(self, "错误", f"无法打开文件: {str(e)}")
                    
    def show_in_explorer(self, index):
        path = self.model.filePath(index)
        result = shell32.ShellExecuteW(None, "explore", os.path.dirname(path), f"/select,\"{path}\"", None, SW_SHOWNORMAL)
        if result <= 32:
            QMessageBox.critical(self, "错误", f"无法在资源管理器中显示: {path}")
            
    def rename_item(self, index):
        old_name = self.model.fileName(index)
        new_name, ok = QInputDialog.getText(self, "重命名", "输入新名称:", text=old_name)
        if ok and new_name:
            old_path = self.model.filePath(index)
            new_path = os.path.join(os.path.dirname(old_path), new_name)
            try:
                os.rename(old_path, new_path)
                self.status_bar.showMessage(f"快捷键: Shift+B 返回上级目录 | 已重命名: {new_name}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"重命名失败: {str(e)}")
                
    def delete_item(self, index):
        path = self.model.filePath(index)
        reply = QMessageBox.question(self, "确认删除", f"确定要删除 {os.path.basename(path)} 吗?", 
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            try:
                if self.model.isDir(index):
                    import shutil
                    shutil.rmtree(path)
                else:
                    os.remove(path)
                self.status_bar.showMessage(f"快捷键: Shift+B 返回上级目录 | 已删除: {os.path.basename(path)}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"删除失败: {str(e)}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = ModernFileManager()
    window.show()
    sys.exit(app.exec())